package com.capinfo.accumulation.service.collection.impl;

import com.capinfo.accumulation.model.collection.*;
import com.capinfo.accumulation.parameter.collection.PauseRecoveryRecordParameter;
import com.capinfo.accumulation.parameter.collection.PersonAccountFundParameter;
import com.capinfo.accumulation.service.collection.PauseRecoveryRecordService;
import com.capinfo.accumulation.service.collection.PersonAccountFundService;
import com.capinfo.commons.project.model.dictionary.Dictionary;
import com.capinfo.framework.dao.SearchCriteria;
import com.capinfo.framework.dao.SearchCriteriaBuilder;
import com.capinfo.framework.dao.impl.restriction.RestrictionExpression;
import com.capinfo.framework.exception.ObjectNotFoundException;
import com.capinfo.framework.service.impl.CommonsDataOperationServiceImpl;
import com.capinfo.framework.util.LogUtils;
import net.sf.json.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by Rexxxar on 2017/10/19.
 */
public class PauseRecoveryRecordServiceImpl extends CommonsDataOperationServiceImpl <PauseRecoveryRecord,PauseRecoveryRecordParameter> implements PauseRecoveryRecordService {

    private static final Log logger = LogFactory.getLog(PauseRecoveryRecord.class);

    public static final BigDecimal RATIO =new BigDecimal(100);

    public static final BigDecimal MONTHPAYP_MIN = new BigDecimal(240);
    public static final BigDecimal MONTHPAY_MAX = new BigDecimal(4800);


    @Autowired
    PersonAccountFundService personAccountFundService;
    /**
     * 停缴查询
     *
     * @Author: Rexxxar
     * @Description
     * @Date: 2017/10/23 18:56
     */
    @Override
    public SearchCriteriaBuilder<PauseRecoveryRecord> getSearchCriteriaBuilder(PauseRecoveryRecordParameter parameter) {
        SearchCriteriaBuilder<PauseRecoveryRecord> searchCriteriaBuilder = super.getSearchCriteriaBuilder(parameter);

        searchCriteriaBuilder.addQueryCondition("pauseRecoveryInventoryId", RestrictionExpression.EQUALS_OP, parameter.getPauseRecoveryInventoryId());

        /*searchCriteriaBuilder.addQueryCondition("personAccountFund.company.gbCompanyAccount", RestrictionExpression.EQUALS_OP, null);*/



        /*searchCriteriaBuilder.addQueryCondition("companyAccountFund.companyAccount", RestrictionExpression.EQUALS_OP, parameter.getEntity().getCompanyAccountFundId());
        searchCriteriaBuilder.addQueryCondition("fundOptionId", RestrictionExpression.EQUALS_OP, parameter.getEntity().getFundOptionId());*//*

        searchCriteriaBuilder.addQueryCondition("person.personalAccount", RestrictionExpression.EQUALS_OP, parameter.getEntity().getPersonId());
        searchCriteriaBuilder.addQueryCondition("companyAccountFund.unitName", RestrictionExpression.EQUALS_OP, parameter.getGbCompanyName());
        searchCriteriaBuilder.addQueryCondition("person.name", RestrictionExpression.EQUALS_OP, parameter.getPerson().getName());
        *//*searchCriteriaBuilder.addQueryCondition("reasonRecord.name", RestrictionExpression.EQUALS_OP, parameter.getEntity().getReasonRecordId());*//*
        searchCriteriaBuilder.addQueryCondition("person.idCardNumber", RestrictionExpression.EQUALS_OP, parameter.getPerson().getIdCardNumber());

*/
        return searchCriteriaBuilder;
    }


    @Override
    public boolean recoveryCheckAccount(String companyAccountFundId) {
        SearchCriteriaBuilder<CompanyAccountFund> searchCriteriaBuilder = new SearchCriteriaBuilder<>(CompanyAccountFund.class);
        searchCriteriaBuilder.addQueryCondition("companyAccount", RestrictionExpression.EQUALS_OP, companyAccountFundId);

        try {
            if(getGeneralService().getObjectByCriteria(searchCriteriaBuilder.build())!=null){
                return true;
            }else{
                return false;
            }
        } catch (ObjectNotFoundException e) {
            return false;
        }
    }

    /**
     * 判断此账户是否可以停复缴
     *@Author: Rexxxar
     *@Description
     *@Date: 2017/10/30 16:18
     */
    public boolean chechOption(String idCardNumber){
        SearchCriteriaBuilder<Person> searchCriteriaBuilder = new SearchCriteriaBuilder<>(Person.class);
        searchCriteriaBuilder.addQueryCondition("personalAccount", RestrictionExpression.EQUALS_OP, idCardNumber);
        Long personId = null;
        Long isPanyment = null;
        List<Person> personList = this.getGeneralService().getObjects(searchCriteriaBuilder.build());
        for(Person person : personList){
            personId  = person.getId();

        }
        SearchCriteriaBuilder<PersonAccountFund> personAccountFundSearchCriteriaBuilder = new SearchCriteriaBuilder<>(PersonAccountFund.class);
        personAccountFundSearchCriteriaBuilder.addQueryCondition("personId", RestrictionExpression.EQUALS_OP, personId);
        List<PersonAccountFund> personAccountFundList = this.getGeneralService().getObjects(personAccountFundSearchCriteriaBuilder.build());
        /*for (PersonAccountFund personAccountFund :personAccountFundList) {
            isPanyment =personAccountFund.getIsPayment();
        }

        //处理一下数据
        if (isPanyment == 1L){
            return true;
        } else {
            return false;
        }*/
        return false;


    }


    @Override
    public List optionFund(Long parameter) {

        SearchCriteriaBuilder<Dictionary> searchCriteriaBuilder = new SearchCriteriaBuilder<>(Dictionary.class);
        searchCriteriaBuilder.addQueryCondition("sortId", RestrictionExpression.EQUALS_OP, parameter);
        searchCriteriaBuilder.addOrderCondition("id", SearchCriteria.OrderRow.ORDER_ASC);

        List<Dictionary> dictionaries = this.getGeneralService().getObjects(searchCriteriaBuilder.build());
        List list = new ArrayList();
        for(Dictionary d : dictionaries){
            Map map = new HashMap();
            map.put("value",d.getId());
            map.put("text",d.getName());
            list.add(map);
        }

        return list;
    }


    public CompanyAccountFund searchRatio(String companyAccount,String idCardNumber) {

        /*Long newpersonPaymentRatio = null;//新单位个人缴存比例
        Long newcompanyPaymentRatio = null;//新单位单位缴存比例
        Long oldpersonPaymentRatio = null;//老单位个人缴存比例
        Long oldcompanyPaymentRatio = null;//老单位单位缴存比例
        Long accumulationFundAccountTypeId = null;//单位公积金账户类型*/


        //查询新单位缴存比例
        //根据单位账号查询出是基本账号还是补充账号
        SearchCriteriaBuilder<CompanyAccountFund> searchCriteriaBuilder = new SearchCriteriaBuilder<>(CompanyAccountFund.class);
        searchCriteriaBuilder.addQueryCondition("companyAccount",RestrictionExpression.EQUALS_OP,companyAccount);
        /*List<CompanyAccountFund> companyAccountFundList = this.getGeneralService().getObjects(searchCriteriaBuilder.build());
        for (CompanyAccountFund companyAccountFund : companyAccountFundList) {
            newpersonPaymentRatio = companyAccountFund.getPersonPaymentRatio();
            newcompanyPaymentRatio = companyAccountFund.getCompanyPaymentRatio();
            accumulationFundAccountTypeId = companyAccountFund.getAccumulationFundAccountTypeId();
        }*/
        try {
            return getGeneralService().getObjectByCriteria(searchCriteriaBuilder.build());
        } catch (ObjectNotFoundException e) {
            return null;
        }

        //查询原单位缴存比例
        //根据单位状态查询
        /*SearchCriteriaBuilder<CompanyAccountFund> companyAccountFundSearchCriteriaBuilder = new SearchCriteriaBuilder<>(CompanyAccountFund.class);
        companyAccountFundSearchCriteriaBuilder.addQueryCondition("person.idCardNumber", RestrictionExpression.EQUALS_OP, idCardNumber);
        companyAccountFundSearchCriteriaBuilder.addQueryCondition("person.accountTypeId", RestrictionExpression.EQUALS_OP, accumulationFundAccountTypeId);
        companyAccountFundSearchCriteriaBuilder.addQueryCondition("person.accountState", RestrictionExpression.EQUALS_OP,0L);
        */
        //判断缴存比例，以新单位为准
        //return getGeneralService().getObjects(personAccountFundSearchCriteriaBuilder.build());
        //return getGeneralService().getObjectByCriteria(searchCriteriaBuilder.build());
        /*try {
            return getGeneralService().getObjectByCriteria(companyAccountFundSearchCriteriaBuilder.build());
        } catch (ObjectNotFoundException e) {
            return null;
        }*/
        /*
        List list = new ArrayList();

        for (PersonAccountFund personAccountFund : personAccountFundList) {
            oldpersonPaymentRatio = personAccountFund.getPersonPaymentRatio();
            oldcompanyPaymentRatio = personAccountFund.getCompanyPaymentRatio();
        }*/


    }

    public PauseRecoveryRecord saveOrUpdateRecord(PauseRecoveryRecordParameter parameter){
    //工资收入存入person表，月缴存额存入personAccountFund表
    // 停复缴标志存入personAccountFund表

        PauseRecoveryRecord source = parameter.getEntity();
        Class<PauseRecoveryRecord> entityClazz = parameter.getEntityClazz();

        PersonAccountFund sourcePerson = parameter.getPersonAccountFund();
        sourcePerson.setId(source.getPersonAccountFundId());
        Class<PersonAccountFund> entityClazzPerson = parameter.getEntityClazzAccount();

        PersonAccountFundParameter personAccountFundParameter = new PersonAccountFundParameter();
        personAccountFundParameter.setEntity(sourcePerson);

        /*parameter.getEntityMessage().getId();*/
        Long id = (null == parameter.getId()) ? source.getId(): parameter.getId();

        if (null == id) {

            try {
                //个人账户为正常缴存的不允许重复进行启封操作
                //通过人的证件号码查询到人的公积金账号(personalAccount)，通过personalAccount在个人公积金账户表里查账户状态。
                //判断此人的个人基本和补充账号是否正常
                Boolean optionId = chechOption(parameter.getIdCardNumber());
                if(optionId == false){
                    return null;
                }
                /*personAccountFundService.getObjectById(personAccountFundParameter).getIsPayment();*/

                getGeneralService().persist(source);

                return source;
            } catch (Exception e) {

                LogUtils.debugException(logger, e);
                throw e;
            }
        }else {

            try {
                PauseRecoveryRecord entity = getGeneralService().getObjectById(entityClazz, id);

                //入库处理逻辑
                getGeneralService().update(entity);

                return entity;
            } catch (Exception e) {

                LogUtils.debugException(logger, e);
                throw e;
            }
        }


    }

    @Override
    public boolean createInventory(PauseRecoveryRecordParameter pauseRecoveryRecordParameter) {


        return true;
    }

    @Override
    public JSONObject recoveryCheckratio(BigDecimal wageIncome, String companyAccount, String idCardNumber) {
        //这个单位账号是新单位账户，原单位账号是根据证件号码取得。
        //根据设置在系统里的缴存额上下限判断
        JSONObject object = new JSONObject();
        CompanyAccountFund companyAccountFund = searchRatio(companyAccount,idCardNumber);
        if (null != companyAccountFund) {

            BigDecimal monthPayPerson = new BigDecimal(companyAccountFund.getPersonPaymentRatio());
            BigDecimal monthPayCompany = new BigDecimal(companyAccountFund.getCompanyPaymentRatio());

            BigDecimal monthPayPersonByNow = wageIncome.multiply(monthPayPerson).multiply(RATIO);
            BigDecimal monthPayCompanyByNow =wageIncome.multiply(monthPayCompany).multiply(RATIO);

            if(monthPayPersonByNow.compareTo(MONTHPAYP_MIN) == -1 || monthPayCompanyByNow.compareTo(MONTHPAY_MAX) == -1){
                //提示缴存基数过低，要按照最低缴存基数缴存
                object.put("result", false);
                object.put("errMsg", "月缴存额过低，要按照最低缴存基数缴存");
                return object;
            }if(monthPayPersonByNow.compareTo(MONTHPAYP_MIN) == 1 || monthPayPersonByNow.compareTo(MONTHPAY_MAX) == -1){
                //提示缴存基数过高，要按照最高缴存基数缴存
                object.put("result", false);
                object.put("errMsg", "月缴存额过高，要按照最高缴存基数缴存");
                return object;
            }else {

                object.put("result", true);
                object.put("monthPay", monthPayPersonByNow.add(monthPayCompanyByNow));
                return object;
            }

        } else {
            object.put("result", false);
            object.put("errMsg", "输入的单位账户或者证件号码错误！");
            return object;
        }

    }


    public CompanyAccountFund searchCompanyAccountAndName( String account) {

        JSONObject object = new JSONObject();

        SearchCriteriaBuilder<CompanyAccountFund> companySearchCriteriaBuilder = new SearchCriteriaBuilder<>(CompanyAccountFund.class);
        companySearchCriteriaBuilder.addQueryCondition("companyAccount",RestrictionExpression.EQUALS_OP,account);


        try {
            return getGeneralService().getObjectByCriteria(companySearchCriteriaBuilder.build());
        } catch (ObjectNotFoundException e) {
            return null;
        }
    }


    @Override
    public JSONObject recoveryCheckPeople(String account,String idCardNumber, Long payment) {
        //根据证件号码查是否可以复缴，如可以返回个人账号 姓名(personAccountFund表) 工资收入(person表)
        JSONObject object = new JSONObject();
        String personalAccount = null;
        BigDecimal wageIncome =new BigDecimal(0);
        Long companyId = null;
        Long companyAccountFundId = null;
        Long personId = null;
        String name = null;
        Long is_payment = null;
        String lastMonthPayment = null;


        SearchCriteriaBuilder<CompanyAccountFund> companyAccountFundSearchCriteriaBuilder = new SearchCriteriaBuilder<>(CompanyAccountFund.class);
        companyAccountFundSearchCriteriaBuilder.addQueryCondition("companyAccount",RestrictionExpression.EQUALS_OP,account);

        List<CompanyAccountFund> companyAccountFundList = this.getGeneralService().getObjects(companyAccountFundSearchCriteriaBuilder.build());
        for(CompanyAccountFund companyAccountFund : companyAccountFundList){
            companyId = companyAccountFund.getCompanyId();
            companyAccountFundId = companyAccountFund.getId();

        }

        SearchCriteriaBuilder<Person> personSearchCriteriaBuilder = new SearchCriteriaBuilder<>(Person.class);
        personSearchCriteriaBuilder.addQueryCondition("idCardNumber",RestrictionExpression.EQUALS_OP,idCardNumber);
        personSearchCriteriaBuilder.addQueryCondition("companyId",RestrictionExpression.EQUALS_OP,companyId);

        //得到个人账号和wageIncome
        List<Person> personList = this.getGeneralService().getObjects(personSearchCriteriaBuilder.build());
        for(Person person : personList){
            personalAccount = person.getPersonalAccount();
            wageIncome = person.getWageIncome();
            name = person.getName();
            personId = person.getId();

        }

        SearchCriteriaBuilder<PersonAccountFund> personAccountFundSearchCriteriaBuilder = new SearchCriteriaBuilder<>(PersonAccountFund.class);
        companyAccountFundSearchCriteriaBuilder.addQueryCondition("companyAccountFundId",RestrictionExpression.EQUALS_OP,companyAccountFundId);
        companyAccountFundSearchCriteriaBuilder.addQueryCondition("personId",RestrictionExpression.EQUALS_OP,personId);

        /*personAccountFundSearchCriteriaBuilder.addQueryCondition("payment",RestrictionExpression.EQUALS_OP,payment);
*/
        List<PersonAccountFund> personAccountFundList = this.getGeneralService().getObjects(personAccountFundSearchCriteriaBuilder.build());
        for(PersonAccountFund personAccountFund : personAccountFundList){
            is_payment = personAccountFund.getPayment();
            lastMonthPayment = personAccountFund.getLastMonthPayment();
        }
        if (is_payment == payment){
            if (payment ==1L){
                object.put("result", false);
                object.put("errMsg", "此账号已是停缴状态，无法再次办理停缴业务。");
                return object;
            } else if(payment ==2L){

                object.put("result", false);
                object.put("errMsg", "此账号已是启封状态，无法再次办理启封业务。");
                return object;
            } else {
                object.put("result", false);
                object.put("errMsg", "账户状态异常");
                return object;
            }
        }else if(payment==1||payment==2){
            if(payment ==1L){
                object.put("lastMonthPayment",lastMonthPayment);
            }
            object.put("result", true);
            object.put("personalAccount",personalAccount);
            object.put("name", name);
            object.put("wageIncome", wageIncome);
            return object;
        }else {
            object.put("result", false);
            object.put("errMsg", "账户状态异常");
            return object;
        }


    }


}
